# Check build environment
ARCH := $(shell uname -m)
ifneq ($(ARCH), loongarch64)
	CROSS_COMPILE ?= loongarch64-linux-gnu-
endif

CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
CPP=$(CROSS_COMPILE)cpp

ifndef S
S:=$(shell cd ../; pwd)
endif

CC_VERSION := $(shell ${CC} -dM -E -x c /dev/null | grep '__GNUC__' | awk '{print $3}')

CACHED_MEMORY_ADDR=0x9000000000000000
UNCACHED_MEMORY_ADDR=0x8000000000000000

CFLAGS= -march=loongarch64  -fno-delayed-branch  -G 0 -mno-memcpy -fno-builtin -c -fno-pic -DCACHED_MEMORY_ADDR=${CACHED_MEMORY_ADDR} -DUNCACHED_MEMORY_ADDR=${UNCACHED_MEMORY_ADDR}
LFLAGS=-m elf64loongarch -G 0 -static -n -nostdlib --allow-multiple-definition
CWARNFLAGS=-Wall -Wstrict-prototypes -Wno-uninitialized -Wno-format -Wno-main
CNOWARNFLAGS=-Wno-uninitialized -Wno-format -Wno-main -Wno-return-type -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch -Wno-incompatible-pointer-types -Wno-implicit-int -fno-stack-protector
CPPFLAGS =-D_KERNEL -D__OpenBSD__ -DPMON -D__PMON__ -mmemcpy -fno-builtin#-march=r4600

CFLAGS += -fno-asynchronous-unwind-tables
ifeq (${TARGET},soc)
CFLAGS += -mstrict-align
else ifeq (${MTUNE},la264)
CFLAGS += -mstrict-align
endif
ifneq ($(CC_VERSION), $(firstword $(sort $(CC_VERSION) 8)))
CFLAGS += ${CNOWARNFLAGS}
endif

INCLUDES=-I${S}/Targets/${TARGET}/compile/${TARGETEL} -I${S}/include \
        -I${S}/Targets/${TARGET}/compile/${TARGETEL}/machine -I${S} \
        -I${S}/Targets/${TARGET}/compile/${TARGETEL}/${TARGET} \
		-I${S}/sys/arch/loongarch/include -I${S}/sys -I${S}/Targets/${TARGET}/${TARGETEL} -I${S}/Targets/${TARGET} \
		-I${S}/pmon/arch/loongarch -nostdinc -fno-strict-aliasing

ifneq "$(findstring $S/x86emu/src,$(CFILES))" ""
		INCLUDES += -I${S}/x86emu/src/x86emu/ -I${S}/x86emu/src/x86emu/include
else
		INCLUDES += -I${S}/x86emu/int10/x86emu/include -I${S}/x86emu/int10/x86emu/src/x86emu/x86emu
endif

export CROSS_COMPILE
export CC += ${CFLAGS} ${MYCC}
export LD += ${LFLAGS} ${MYLD}
export MKDEP=makedepend

OUT_FORMAT="elf64-loongarch"

GZROMSTARTADDR?=${CACHED_MEMORY_ADDR}+0x90000000
ROMSTARTADDR?=${CACHED_MEMORY_ADDR}+0xf010000
RAMSTARTADDR?=${CACHED_MEMORY_ADDR}+0x8000000

gencode=./genrom
SHELL=/bin/bash

all: ${tgt}
ifeq (${TARGET},ls3a5000_7a)
rom: clean acpi ${START} zloader.o cache_stage.o
else ifeq (${TARGET},ls2k)
rom: clean acpi ${START} zloader.o cache_stage.o
else
rom: clean ${START} zloader.o cache_stage.o
endif
	${CC}  -I./sys/arch/loongarch/include/ -DSTARTADDR=${GZROMSTARTADDR} -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=loongarch -Uloongarch -DGZROMLDS -E -P ld.script.S  > ld.script
	${LD} -T ld.script -e start -o gzrom ${START} zloader.o cache_stage.o ${TARGET_LIB} ${DEBUG}
	${CROSS_COMPILE}objcopy -O binary gzrom gzrom.bin
	sed -i 's/__attribute__((section(".biosdata")))//' pmon.bin.c
	${CC} -D_LOCORE -G 0 ${CPPFLAGS} ${IDENT_DEF} ${INCLUDES} $$((cat ../Targets/${TARGET}/${TARGETEL}/start.S; echo COM1_BASE_ADDR; ) | (printf " -DCOM1_BASE_ADDR=0x%x" $$(($$(${CC} -D_LOCORE -G 0 ${AFLAGS} ${CPPFLAGS} ${IDENT_DEF} ${INCLUDES}  -g3 -nostdinc -D__ASSEMBLY__ -E -x assembler-with-cpp - |tail -n 1)));)) -g -c startram.S -o startram.o
	$(CC) -DISGZRAM -c zloader.c -g -o zloader1.o ${ZLOADER_OPTIONS} -DMEMSIZE=${MEMSIZE}
	${LD} -T ld.script -g -e start -o gzram startram.o zloader1.o ${TARGET_LIB}
	${CROSS_COMPILE}objcopy -O binary gzram gzram.bin

${START}: ../Targets/${TARGET}/${TARGETEL}/start.S
	${CC} -D_LOCORE -G 0 ${CPPFLAGS} ${IDENT_DEF} ${INCLUDES} ${DEBUG} -c $< -o $@
	${CC} -DSTARTADDR=${ROMSTARTADDR} -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=loongarch -Uloongarch -E -P ld.script.S  > ../Targets/${TARGET}/conf/ld.script
	make -C ../Targets/${TARGET}/compile/${TARGETEL}/

cache_stage.o: ../Targets/${TARGET}/cache_stage/cache_stage.c
	${CC} -O2 ${CPPFLAGS} ${IDENT_DEF} ${INCLUDES} -c $< -o $@

zloader.o: zloader.c inflate.c  malloc.c  memop.c  pmon.bin.c init_loongarch.c
	$(CC) -c zloader.c ${IDENT_DEF} ${ZLOADER_OPTIONS} -DMEMSIZE=${MEMSIZE} ${DEBUG}

init_loongarch.c:  ../Targets/${TARGET}/compile/${TARGETEL}/pmon
	${gencode} $< > init_loongarch.c

pmon.bin.c:  ../Targets/${TARGET}/compile/${TARGETEL}/pmon.bin
	gzip $< -c > pmon.bin.gz
	./bin2c pmon.bin.gz pmon.bin.c biosdata

dtb:
	make -C ../tools/dtc-1.7.0/ CC=gcc || echo -e "\e[33mWARNING: DTC compilation failed but may not fatal \e[0m"
ifeq (${MTUNE},la264)
	cp `pwd`/../Targets/${TARGET}/conf/ls2k1500.dts `pwd`/${TARGETEL}.dtb.i
else ifeq (${MTUNE},la364)
	cp `pwd`/../Targets/${TARGET}/conf/ls2k2000.dts `pwd`/${TARGETEL}.dtb.i
else 
ifeq (${TARGETEL},ls2k300)
	cp `pwd`/../Targets/${TARGET}/conf/2k0300-pinctrl.dtsi `pwd`/
	cp `pwd`/../Targets/${TARGET}/conf/loongson_2k0300.dtsi `pwd`/
else 
ifeq (${TARGETEL},ls2k500)
	cp `pwd`/../Targets/${TARGET}/conf/ls2k500.dtsi `pwd`/
else 
ifeq (${TARGETEL},ls2k1000)
	cp `pwd`/../Targets/${TARGET}/conf/ls2k1000.dtsi `pwd`/
endif
endif
endif
	cp `pwd`/../Targets/${TARGET}/conf/${TARGETEL}.dts `pwd`/${TARGETEL}.dtb.i
endif
	sed -i "s/DTS_CORE_FREQ/${DTS_CORE_FREQ}/g" `pwd`/${TARGETEL}.dtb.i
	make -C ../Targets/${TARGET}/compile/${TARGETEL}/ DTB_O=`pwd`/${TARGETEL}.dtb.ii DTB_I=`pwd`/${TARGETEL}.dtb.i dtb
	../tools/dtc-1.7.0/dtc -q -I dts -O dtb -o ${TARGETEL}.dtb  ${TARGETEL}.dtb.ii
	( echo  "#include <include/load_dtb.h>";echo NVRAM_OFFS; echo DTB_OFFS; )| make -C ../Targets/${TARGET}/compile/${TARGETEL}/ DTB_O=`pwd`/dtbinfo.txt DTB_I=- dtb
ifeq (${TARGETEL},ls2k300)
	[ -f gzrom.bin ] && cp gzrom.bin gzrom-dtb.bin && python ../tools/pmonenv-ls2k300.py -O $$((`tail -n 1 dtbinfo.txt`)) -o $$((`tail -n 2 dtbinfo.txt|head -n 1`)) -f gzrom-dtb.bin -d ${TARGETEL}.dtb -w  al=\(usb0,0\)/boot/vmlinuz al1=\(emmc0,0\)/boot/vmlinuz_golden append="'console=ttyS0,115200'" FR=1
else
	[ -f gzrom.bin ] && cp gzrom.bin gzrom-dtb.bin && python ../tools/pmonenv.py -O $$((`tail -n 1 dtbinfo.txt`)) -o $$((`tail -n 2 dtbinfo.txt|head -n 1`)) -f gzrom-dtb.bin -d ${TARGETEL}.dtb -w  al=\(usb0,0\)/boot/vmlinuz al1=\(emmc0,0\)/boot/vmlinuz_golden append="'console=ttyS0,115200'" FR=1
endif
cleanall: clean
	make -C ../tools/pmoncfg/  clean
	make -C ../tools/dtc-1.7.0/ clean
	make -C ../Targets/${TARGET}/compile/${TARGETEL}/ clean
	find ../ -name dvfs.h -o -name buildpmon.log |xargs  rm -rf
clean:
	rm -rf *.o zlib_gzip zloader pmon.bin.c gzrom *.bin gzram *.dtb *.dtsi dtbinfo.txt init_loongarch.c pmon.bin.gz zlib_deflate/*.o zlib_inflate/*.o zlib_gzrom zlib_gzrom.bin ${TARGET_LIB}
	rm $(ASL_DIR)/dsdt.c $(ASL_DIR)/*.tmp $(ASL_DIR)/*.aml -rf

cfg%:
	# DO NOT DELETE
	perl -i -ne 'print;exit if(/^# DO NOT DELETE/);' ../lib/libc/Makefile
	perl -i -ne 'print;exit if(/^# DO NOT DELETE/);' ../lib/libm/Makefile
	perl -i -ne 'print;exit if(/^# DO NOT DELETE/);' ../lib/libz/Makefile
	make -C ../tools/pmoncfg/ CC=gcc
	mkdir -p ../Targets/${TARGET}/compile
	cd ../Targets/${TARGET}/conf/;../../../tools/pmoncfg/pmoncfg -s ../../../.. -b ../compile/${TARGETEL} $(@:cfg%=%)
	make -C ../Targets/${TARGET}/compile/${TARGETEL}/ depend clean
	${TARGET_CFG}
	perl -i -ne 'print;exit if(/^# DO NOT DELETE/);' ../lib/libc/Makefile
	perl -i -ne 'print;exit if(/^# DO NOT DELETE/);' ../lib/libm/Makefile
	perl -i -ne 'print;exit if(/^# DO NOT DELETE/);' ../lib/libz/Makefile
cfg:
	#$(cfg${TARGETEL}) TARGET_CFG=${TARGET_CFG}
	make -f Makefile  cfg${TARGETEL}

ls2k1000:
	@cp ../Targets/${TARGET}/conf/ls2k1000 ../Targets/${TARGET}/conf/.conf
ls2k500:
	@cp ../Targets/${TARGET}/conf/ls2k500 ../Targets/${TARGET}/conf/.conf
ls2k300:
	@cp ../Targets/${TARGET}/conf/ls2k300 ../Targets/${TARGET}/conf/.conf
